//
// Created by HP on 2025/11/5.
//

#include "../include/middleware.h"
#include "../model/user.h"

bool Middleware::requiredAuth(const Request& req) {
//    std::cout<<1<<std::endl;
    req.show();
    if(req.headers.find("Authorization") == req.headers.end() && req.headers.find("authorization") == req.headers.end()){
        return false;
    }

    std::string token;
    if (req.headers.find("Authorization") != req.headers.end()){
        token = req.headers.at("Authorization");
    } else {
        token = req.headers.at("authorization");
    }
    
//    std::cout<<token<<std::endl;
    std::vector<std::string> splits=split(token, ' ');
    if (splits.size() != 2 || splits[0] != "Bearer") {
        return false;
    }
    return JWT::getInstance()->verifyToken(splits[1]);
}

bool Middleware::requiredAdmin(const Request& req) {
//    req.show();
    if(req.headers.find("Authorization") == req.headers.end() && req.headers.find("authorization") == req.headers.end()){
        return false;
    }

    std::string token;
    if (req.headers.find("Authorization") != req.headers.end()){
        token = req.headers.at("Authorization");
    } else {
        token = req.headers.at("authorization");
    }
//    std::cout<<token<<std::endl;
    std::vector<std::string> splits=split(token, ' ');
    if (splits.size() != 2 || splits[0] != "Bearer") {
        return false;
    }

    auto claims = JWT::getInstance()->parseClaims(splits[1]);
    if (!claims->count("id")) {
        return false;
    }
    std::string id_str = claims->at("id");
    int id;
    try{
        id = std::stoi(id_str);
    }catch (std::exception& e) {
        return false;
    }

//    std::cout<<id<<std::endl;

    User user;
    user.bind("id", std::to_string(id));
    return user.role == Role::SuperAdmin;
}

std::string Middleware::extractToken(const std::string &request) {
    return {};
}

int Middleware::GetCurrentUser(const Request& req) {
    if(req.headers.find("Authorization") == req.headers.end() && req.headers.find("authorization") == req.headers.end()){
        return 0;
    }

    std::string token;
    if (req.headers.find("Authorization") != req.headers.end()){
        token = req.headers.at("Authorization");
    } else {
        token = req.headers.at("authorization");
    }
    std::vector<std::string> splits=split(token, ' ');
    if (splits.size() != 2 || splits[0] != "Bearer") {
        return 0;
    }

    auto claims = JWT::getInstance()->parseClaims(splits[1]);
    if (!claims->count("id")) {
        return false;
    }
    std::string id_str = claims->at("id");
    int id;
    try{
        id = std::stoi(id_str);
    }catch (std::exception& e) {
        return 0;
    }

    return id;
}

bool Middleware::requiredMaintenance(const Request &req) {
    if(req.headers.find("Authorization") == req.headers.end() && req.headers.find("authorization") == req.headers.end()){
        return false;
    }

    std::string token;
    if (req.headers.find("Authorization") != req.headers.end()){
        token = req.headers.at("Authorization");
    } else {
        token = req.headers.at("authorization");
    }
//    std::cout<<token<<std::endl;
    std::vector<std::string> splits=split(token, ' ');
    if (splits.size() != 2 || splits[0] != "Bearer") {
        return false;
    }

    auto claims = JWT::getInstance()->parseClaims(splits[1]);
    if (!claims->count("id")) {
        return false;
    }
    std::string id_str = claims->at("id");

    int id;
    try{
        id = std::stoi(id_str);
    }catch (std::exception& e) {
        return false;
    }

//    std::cout<<id<<std::endl;

    User user;
    user.bind("id", std::to_string(id));
    return  user.role == Role::SuperAdmin || user.role == Role::MaintenanceAdmin;

}

bool Middleware::requiredContent(const Request &req) {
//    req.show();
    if(req.headers.find("Authorization") == req.headers.end() && req.headers.find("authorization") == req.headers.end()){
        return false;
    }

    std::string token;
    if (req.headers.find("Authorization") != req.headers.end()){
        token = req.headers.at("Authorization");
    } else {
        token = req.headers.at("authorization");
    }
//    std::cout<<token<<std::endl;
    std::vector<std::string> splits=split(token, ' ');
    if (splits.size() != 2 || splits[0] != "Bearer") {
        return false;
    }

    auto claims = JWT::getInstance()->parseClaims(splits[1]);
    if (!claims->count("id")) {
        return false;
    }
    std::string id_str = claims->at("id");
    int id;
    try{
        id = std::stoi(id_str);
    }catch (std::exception& e) {
        return false;
    }

//    std::cout<<id<<std::endl;

    User user;
    user.bind("id", std::to_string(id));
    return user.role == Role::SuperAdmin || user.role == Role::ContentAdmin;

}

bool Middleware::requiredMoney(const Request &req) {
    if(req.headers.find("Authorization") == req.headers.end() && req.headers.find("authorization") == req.headers.end()){
        return false;
    }

    std::string token;
    if (req.headers.find("Authorization") != req.headers.end()){
        token = req.headers.at("Authorization");
    } else {
        token = req.headers.at("authorization");
    }
//    std::cout<<token<<std::endl;
    std::vector<std::string> splits=split(token, ' ');
    if (splits.size() != 2 || splits[0] != "Bearer") {
        return false;
    }

    const std::string id_str = JWT::getInstance()->parseClaims(splits[1])->at("id");
    int id;
    try{
        id = std::stoi(id_str);
    }catch (std::exception& e) {
        return false;
    }

    User user;
    user.bind("id", std::to_string(id));
    return user.role == Role::SuperAdmin || user.role == Role::MoneyAdmin;
}
